package com.atlin.project.service.task.impl;

import cn.hutool.core.date.DateUtil;
import com.atlin.project.common.ErrorCode;
import com.atlin.project.contant.CommonConstant;
import com.atlin.project.exception.BusinessException;
import com.atlin.project.exception.ThrowUtils;
import com.atlin.project.mapper.task.UserTasksMapper;
import com.atlin.project.model.domain.SysUser;
import com.atlin.project.model.domain.task.SpacesUserTask;
import com.atlin.project.model.domain.task.TaskSpaces;
import com.atlin.project.model.domain.task.UserTasks;
import com.atlin.project.model.dto.userTasks.UserTasksAddRequest;
import com.atlin.project.model.dto.userTasks.UserTasksEditRequest;
import com.atlin.project.model.dto.userTasks.UserTasksQueryRequest;
import com.atlin.project.model.enums.task.UserTaskPriorityEnum;
import com.atlin.project.model.enums.task.UserTaskStatusEnum;
import com.atlin.project.model.vo.UserTasksVO;
import com.atlin.project.service.task.SpacesUserTaskService;
import com.atlin.project.service.task.TaskSpacesService;
import com.atlin.project.service.task.UserTasksService;
import com.atlin.project.utils.sql.SqlUtils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author atlin
 * @description userTasks
 * @createDate date
 */
@Slf4j
@Service
public class UserTasksServiceImpl extends ServiceImpl<UserTasksMapper, UserTasks>
        implements UserTasksService {

    @Resource
    private TaskSpacesService taskSpacesService;

    @Resource
    private SpacesUserTaskService spacesUserTaskService;

    @Override
    public void validAndFill(UserTasks userTasks, boolean add) {
        String status = userTasks.getStatus();
        String priority = userTasks.getPriority();
        Date dueDate = userTasks.getDueDate();
        Integer estimatedTime = userTasks.getEstimatedTime();
        if (add) {
            UserTaskStatusEnum statusEnum = UserTaskStatusEnum.getEnumByValue(status);
            if (statusEnum == null) {
                userTasks.setStatus(UserTaskStatusEnum.IN_PROGRESS.getValue());
            }

            UserTaskPriorityEnum priorityEnum = UserTaskPriorityEnum.getEnumByValue(priority);
            if (priorityEnum == null) {
                userTasks.setPriority(UserTaskPriorityEnum.MEDIUM.getValue());
            }
            if (dueDate == null) {
                // 默认截止日期为一周
                userTasks.setDueDate(DateUtil.offsetWeek(new Date(), 1));
            }
            if (estimatedTime == null || estimatedTime == 0) {
                final Integer ONE_WEEK = 7 * 24 * 60;
                userTasks.setEstimatedTime(ONE_WEEK);
            }
        } else {
            if (StringUtils.isNotBlank(status)) {
                UserTaskStatusEnum statusEnum = UserTaskStatusEnum.getEnumByValue(status);
                UserTaskPriorityEnum priorityEnum = UserTaskPriorityEnum.getEnumByValue(priority);
                ThrowUtils.throwIf(statusEnum == null, ErrorCode.PARAMS_ERROR);
            }
            if (StringUtils.isNotBlank(priority)) {
                UserTaskPriorityEnum priorityEnum = UserTaskPriorityEnum.getEnumByValue(priority);
                ThrowUtils.throwIf(priorityEnum == null, ErrorCode.PARAMS_ERROR);
            }

        }
    }

    @Override
    public UserTasksVO getUserTasksVO(UserTasks userTasks, HttpServletRequest request) {
        UserTasksVO userTasksVO = UserTasksVO.objToVo(userTasks);
        // todo other operation
        return userTasksVO;
    }

    /**
     * 获取查询包装类（用户根据哪些字段查询，根据前端传来的请求对象，得到 mybatis 框架支持的查询 QueryWrapper 类）
     *
     * @param userTasksQueryRequest
     * @return
     */
    @Override
    public QueryWrapper<UserTasks> getQueryWrapper(UserTasksQueryRequest userTasksQueryRequest) {
        QueryWrapper<UserTasks> queryWrapper = new QueryWrapper<>();
        if (userTasksQueryRequest == null) {
            return queryWrapper;
        }
        Long id = userTasksQueryRequest.getId();
        Long taskSpaceId = userTasksQueryRequest.getTaskSpaceId();
        String title = userTasksQueryRequest.getTitle();
        String sortField = userTasksQueryRequest.getSortField();
        String sortOrder = userTasksQueryRequest.getSortOrder();
        String searchText = userTasksQueryRequest.getSearchText();

        String description = userTasksQueryRequest.getDescription();
        String status = userTasksQueryRequest.getStatus();
        String priority = userTasksQueryRequest.getPriority();
        Date dueDate = userTasksQueryRequest.getDueDate();
        Date createTime = userTasksQueryRequest.getCreatedTime();
        Date updateTime = userTasksQueryRequest.getUpdateTime();
        Date completedTime = userTasksQueryRequest.getCompletedTime();
        Integer estimatedTime = userTasksQueryRequest.getEstimatedTime();
        Long parentTaskId = userTasksQueryRequest.getParentTaskId();


        queryWrapper.like(StringUtils.isNotBlank(title), "title", title);
        queryWrapper.like(StringUtils.isNotBlank(description), "description", description);
        queryWrapper.like(StringUtils.isNotBlank(searchText), "description", searchText);
        queryWrapper.like(StringUtils.isNotBlank(searchText), "title", searchText);

        queryWrapper.like(StringUtils.isNotBlank(status), "status", status);
        queryWrapper.like(StringUtils.isNotBlank(priority), "priority", priority);
        queryWrapper.le(ObjectUtils.isNotEmpty(dueDate), "dueDate", dueDate);
        queryWrapper.le(ObjectUtils.isNotEmpty(completedTime), "completedTime", completedTime);
        queryWrapper.eq(ObjectUtils.isNotEmpty(estimatedTime), "estimatedTime", estimatedTime);
        queryWrapper.eq(ObjectUtils.isNotEmpty(id), "id", id);
        queryWrapper.eq(ObjectUtils.isNotEmpty(parentTaskId), "parentTaskId", parentTaskId);
        queryWrapper.orderBy(SqlUtils.validSortField(sortField),
                sortOrder.equals(CommonConstant.SORT_ORDER_ASC), sortField);

        return queryWrapper;
    }

    @Override
    public Page<UserTasksVO> getUserTasksVOPage(Page<UserTasks> userTasksPage, HttpServletRequest request) {
        List<UserTasks> userTasksList = userTasksPage.getRecords();
        Page<UserTasksVO> userTasksVOPage = new Page<>(userTasksPage.getCurrent(), userTasksPage.getSize(), userTasksPage.getTotal());
        if (CollectionUtils.isEmpty(userTasksList)) {
            return userTasksVOPage;
        }
        // todo other operation

        // 填充信息
        List<UserTasksVO> userTasksVOList = userTasksList.stream().map(userTasks -> {
            UserTasksVO userTasksVO = UserTasksVO.objToVo(userTasks);
            // todo other operation

            return userTasksVO;
        }).collect(Collectors.toList());
        userTasksVOPage.setRecords(userTasksVOList);
        return userTasksVOPage;
    }

    @Override
    public Page<UserTasksVO> getMyUserTasksVOPage(UserTasksQueryRequest userTasksQueryRequest) {
        QueryWrapper<UserTasks> wrapper = this.getQueryWrapper(userTasksQueryRequest);
        Long taskSpaceId = userTasksQueryRequest.getTaskSpaceId();
        long size = userTasksQueryRequest.getPageSize();
        long current = userTasksQueryRequest.getCurrent();
        Page<UserTasks> userTasksPage;
        if (taskSpaceId != null && taskSpaceId > 0) {
            userTasksPage = baseMapper.queryPageMyUserTask(new Page<>(current, size), taskSpaceId, wrapper);
        } else {
            userTasksPage = this.page(new Page<>(current, size), wrapper);
        }

        List<UserTasks> records = userTasksPage.getRecords();
        Page<UserTasksVO> userTasksVOPage = new Page<>(current, size, userTasksPage.getTotal());
        if (records.isEmpty()) {
            return userTasksVOPage;
        }
        List<UserTasksVO> tasksVOList = records.stream().map(UserTasksVO::objToVo).collect(Collectors.toList());
        userTasksVOPage.setRecords(tasksVOList);

        return userTasksVOPage;
    }

    /**
     * 创建任务
     *
     * @param userTasksAddRequest r
     * @param loginUser           u
     * @return i
     */
    @Override
    @Transactional
    public Long createUserTask(UserTasksAddRequest userTasksAddRequest, SysUser loginUser) {
        UserTasks userTasks = new UserTasks();
        BeanUtils.copyProperties(userTasksAddRequest, userTasks);
        this.validAndFill(userTasks, true);
        Long taskSpaceId = userTasksAddRequest.getTaskSpaceId();
        ThrowUtils.throwIf(taskSpaceId == null || taskSpaceId <= 0, ErrorCode.PARAMS_ERROR, "任务空间不存在");

        TaskSpaces taskSpaces = taskSpacesService.getById(taskSpaceId);
        ThrowUtils.throwIf(taskSpaces == null, ErrorCode.NULL_ERROR, "任务空间不存在");

        boolean save = save(userTasks);
        if (save) {
            SpacesUserTask spacesUserTask = new SpacesUserTask();
            spacesUserTask.setUserTaskId(userTasks.getId());
            spacesUserTask.setSpaceId(taskSpaces.getId());

            boolean r = spacesUserTaskService.save(spacesUserTask);
            if (!r) {
                throw new BusinessException(ErrorCode.OPERATION_ERROR);
            }
            return userTasks.getId();
        }

        return 0L;
    }

    @Override
    public boolean editUserTask(UserTasksEditRequest userTasksEditRequest, SysUser loginUser) {
        Long id = userTasksEditRequest.getId();
        Long space = userTasksEditRequest.getSpace();
        String title = userTasksEditRequest.getTitle();
        String description = userTasksEditRequest.getDescription();
        String status = userTasksEditRequest.getStatus();
        String priority = userTasksEditRequest.getPriority();

        if (id == null || id <= 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        UserTasks userTasks = this.getById(id);
        if (userTasks == null) {
            throw new BusinessException(ErrorCode.NULL_ERROR);
        }
        QueryWrapper<SpacesUserTask> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(SpacesUserTask::getUserTaskId, id);
        SpacesUserTask spacesUserTask = spacesUserTaskService.getOne(wrapper);
        if (spacesUserTask == null) {
            log.error("数据存在错误");
            throw new BusinessException(ErrorCode.SYSTEM_ERROR);
        }

        userTasks = new UserTasks();
        BeanUtils.copyProperties(userTasksEditRequest, userTasks);

        validAndFill(userTasks, false);

        return updateById(userTasks);
    }

}




